package com.example.tongyao.system.config;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

/**
 * 访问权限管理
 *
 * @version 1.0
 * @author tongyao
 * @since 2020-06-13
 */
@Configuration
public class ShiroConfig {

    @Value("${api.security.path}")
    String apiPath;

    Logger logger = (Logger) LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);

        //无登录的跳转的提示
        bean.setLoginUrl("/defaultLogin");

        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        //anon不需要验证的接口
        //filterChainDefinitionMap.put("/login", "anon");
        //filterChainDefinitionMap.put("/swagger-ui.html", "anon");
		//filterChainDefinitionMap.put("/swagger-resources/**", "anon");
		//filterChainDefinitionMap.put("/v2/api-docs/**", "anon");
		//filterChainDefinitionMap.put("/webjars/springfox-swagger-ui/**", "anon");
        //filterChainDefinitionMap.put("/druid/**", "anon");

        //filterChainDefinitionMap.put("/**", "user");

        ////authc必须登录后才可以验证的
        //filterChainDefinitionMap.put("/user/index", "authc");

        logger.debug(apiPath);
        String[] path = apiPath.split(",");
        for(String strPath : path){
            String[] params = strPath.split(":");
            filterChainDefinitionMap.put(params[0], params[1]);
        }

        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }


    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        return manager;
    }

    @Bean("authRealm")
    public AuthRealm authRealm(@Qualifier("credentialMatcher") CredentialMatcher matcher) {
        AuthRealm authRealm = new AuthRealm();
        authRealm.setCacheManager(new MemoryConstrainedCacheManager());
        authRealm.setCredentialsMatcher(matcher);
        return authRealm;
    }

    @Bean("credentialMatcher")
    public CredentialMatcher credentialMatcher() {
        return new CredentialMatcher();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    /*此处为解决每次启动项目 session就得刷新问题，才加入的redis缓存*/
    /*public RedisManager redisManager() {
        CustomRedisManager redisManager = new CustomRedisManager();
        redisManager.setHost("localhost");
        redisManager.setPort(6379);
        redisManager.setDatabase(1);
        redisManager.setTimeout(0);
        redisManager.setPassword(null);
        return redisManager;
    }*/

    /*public RedisSessionDAO redisSessionDAO() {
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        return redisSessionDAO;
    }*/

    @Bean("sessionManager")
    public DefaultWebSessionManager defaultWebSessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//        sessionManager.setGlobalSessionTimeout(1800000); //设置全局会话超时时间，默认30分钟(1800000)
        //sessionManager.setSessionDAO(redisSessionDAO());
        return sessionManager;
    }
}